package com.zwxbc.funplay.servlet;

import com.google.gson.Gson;
import com.zwxbc.funplay.entity.Player;
import com.zwxbc.funplay.service.PlayerService;
import com.zwxbc.funplay.service.impl.PlayerServiceImpl;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.nio.file.Paths;
import java.util.List;

@WebServlet("/player")
public class PlayerServlet extends HttpServlet {
	PlayerService playerService = new PlayerServiceImpl();

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
		request.setCharacterEncoding("UTF-8");

		String action = request.getParameter("action");

		if ("getAll".equals(action)) {
			// 获取所有玩家数据
			handleGetList(request, response);
		} else if ("getById".equals(action)) {
			// 获取单个玩家数据
			handleGetById(request, response);
		} else {
			// 未知的操作类型
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			response.getWriter().println("未知的操作");
		}
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		String action = request.getParameter("action");

		System.out.println(action);
		if ("add".equals(action)) {
			// 添加玩家
			handleAdd(request, response);
		} else if ("update".equals(action)) {
			// 更新玩家
			handleUpdate(request, response);
		} else if ("delete".equals(action)) {
			// 删除玩家
			handleDelete(request, response);
		} else if ("login".equals(action)) {
			// 玩家登录
			handleLogin(request, response);
		} else {
			// 未知的操作类型
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			response.getWriter().println("Unknown action");
		}
	}

	private void handleUpdate(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {

		response.setContentType("text/html;charset=UTF-8");
		request.setCharacterEncoding("UTF-8");

		// 创建DiskFileItemFactory对象，设置缓冲区大小和临时文件目录
		FileItemFactory factory = new DiskFileItemFactory();
		// 创建ServletFileUpload对象，设置上传文件的大小限制
		ServletFileUpload upload = new ServletFileUpload(factory);
		upload.setFileSizeMax(10 * 1024 * 1024); // 单个文件最大上传10MB
		upload.setSizeMax(50 * 1024 * 1024); // 总共最大上传50MB
		upload.setHeaderEncoding("UTF-8");

		Player player = new Player();

		try {
			List<FileItem> items = upload.parseRequest(request);

			for (FileItem item : items) {
				// 若为form表单字段
				if (item.isFormField()) {
					String fieldName = item.getFieldName();
					String fieldValue = item.getString("UTF-8");
					switch (fieldName) {
						case "username": player.setPlayerUsername(fieldValue); break;
						case "name": player.setPlayerName(fieldValue); break;
						case "email": player.setPlayerEmail(fieldValue); break;
						case "contact": player.setPlayerContact(fieldValue); break;
						default: break;
					}
				} else { // 若为文件字段
					String fileName = Paths.get(item.getName()).getFileName().toString(); // 从完整路径中提取文件名
					if (!fileName.isEmpty()) {
						// 指定存放上传图片的目录，根据实际情况修改路径
						String imagePath = "E:\\MyPractice\\homework\\funplay\\src\\main\\webapp\\img\\user\\";
						File uploadPath = new File(imagePath);
						if (!uploadPath.exists() && !uploadPath.mkdirs()) {
							throw new IOException("创建目录失败：" + imagePath);
						}
						// 保存上传的文件
						File file = new File(uploadPath, fileName);
						try (InputStream inputStream = item.getInputStream();
						     FileOutputStream outputStream = new FileOutputStream(file)) {
							byte[] buffer = new byte[1024];
							int bytesRead;
							while ((bytesRead = inputStream.read(buffer)) != -1) {
								outputStream.write(buffer, 0, bytesRead);
							}
						} catch (IOException e) {
							throw new IOException("无法保存文件：" + fileName, e);
						}
						item.write(file); // 写入文件
						player.setPlayerImage(fileName); // 设置player的image属性
					}
				}
			}

			if (player.getPlayerImage() == null) {
				Player existingPlayer = (Player) request.getSession().getAttribute("user");
				player.setPlayerImage(existingPlayer.getPlayerImage());
			}

			boolean isUpdated = playerService.playerUpdate(player);
			if (!isUpdated) {
				// 处理更新失败的情况
				request.setAttribute("message", "无法更新玩家信息。");
			}

		} catch (Exception e) {
			e.printStackTrace();
			request.setAttribute("message", "文件上传失败：" + e.getMessage());
		}

		Player playerByUsername = playerService.getPlayerByUsername(player.getPlayerUsername());
		HttpSession session = request.getSession();
		session.setAttribute("user", playerByUsername);
		session.setAttribute("message", "信息已成功更新");

		// 请求转发至JSP页面展示信息更新结果
		request.getRequestDispatcher("/view/player/store.jsp").forward(request, response);
	}

	// 添加新玩家
	private void handleAdd(HttpServletRequest request, HttpServletResponse response) throws IOException {
		// 从请求中提取参数
		String playerName = request.getParameter("playerName");
		String playerUserName = request.getParameter("playerUsername");
		String playerEmail = request.getParameter("playerEmail");
		String playerContact = request.getParameter("playerContact");

		// 创建一个 Player 对象
		Player newPlayer = new Player();
		newPlayer.setPlayerName(playerName);
		newPlayer.setPlayerContact(playerContact);
		newPlayer.setPlayerUsername(playerUserName);
		newPlayer.setPlayerEmail(playerEmail);
		newPlayer.setPlayerLevel(0L);
		newPlayer.setPlayerImage("user.png");

		// 调用服务方法添加新玩家
		boolean success = playerService.addPlayer(newPlayer);

		// 发送响应
		sendJsonResponse(response, "{\"success\":" + success + "}");
	}

	private void handleLogin(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		String playerUsername = request.getParameter("username");
		String playerPassword = request.getParameter("password");
		String gameId = request.getParameter("gameId");
		Player player = new Player();
		player.setPlayerUsername(playerUsername);
		player.setPlayerEmail(playerUsername);
		player.setPlayerContact(playerUsername);
		player.setPlayerPassword(playerPassword);
		PlayerService playerService = new PlayerServiceImpl();
		Player authenticatedPlayer = playerService.playerLogin(player);

		if (authenticatedPlayer != null) {
			// 登录成功
			request.getSession().setAttribute("user", authenticatedPlayer);
			request.setAttribute("gameId", gameId);
			request.getRequestDispatcher("/view/player/gameInfo.jsp").forward(request, response);
		} else {
			// 登录失败
			String errorMessage = "账号或密码错误";
			request.setAttribute("errorMessage", errorMessage);
			// 转发回登录页面
			request.getRequestDispatcher("/view/player/playerLogin.jsp").forward(request, response);
		}

	}

	// 删除玩家
	private void handleDelete(HttpServletRequest request, HttpServletResponse response) throws IOException {
		// 从请求中提取参数
		String playerId = request.getParameter("playerId");

		// 调用服务方法删除玩家
		boolean success = playerService.deletePlayer(Long.parseLong(playerId));

		// 发送响应
		sendJsonResponse(response, "{\"success\":" + success + "}");
	}

	// 根据ID查询玩家
	private void handleGetById(HttpServletRequest request, HttpServletResponse response) throws IOException {
		// 从请求中提取参数
		String playerIdParam = request.getParameter("playerId");

		Long playerId = Long.parseLong(playerIdParam);

		// 调用方法根据ID获取玩家
		Player player = playerService.getPlayerById(playerId);

		// 将 Player 对象转换为 JSON 并发送响应
		String jsonData = new Gson().toJson(player);
		sendJsonResponse(response, jsonData);
	}


	private void handleGetList(HttpServletRequest request, HttpServletResponse response) throws IOException {
		List<Player> playerList = playerService.getPlayerList();
		// 将 Player 对象转换为 JSON 并发送响应
		String jsonData = new Gson().toJson(playerList);
		sendJsonResponse(response, jsonData);
	}

	private void sendJsonResponse(HttpServletResponse response, String jsonData) throws IOException {
		response.setContentType("application/json");
		response.setCharacterEncoding("UTF-8");
		PrintWriter out = response.getWriter();
		out.print(jsonData);
		out.flush();
	}
}
